<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 6.3.0">
  <link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
  <link rel="icon" type="image/png" sizes="32x32" href="/images/favicon.jpg">
  <link rel="icon" type="image/png" sizes="16x16" href="/images/favicon.jpg">
  <link rel="mask-icon" href="/images/logo.svg" color="#222">

<link rel="stylesheet" href="/css/main.css">


<link rel="stylesheet" href="/lib/font-awesome/css/all.min.css">

<script id="hexo-configurations">
    var NexT = window.NexT || {};
    var CONFIG = {"hostname":"matian.connorma.cn","root":"/","scheme":"Muse","version":"7.8.0","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12,"onmobile":false},"copycode":{"enable":false,"show_result":false,"style":null},"back2top":{"enable":true,"sidebar":false,"scrollpercent":false},"bookmark":{"enable":false,"color":"#222","save":"auto"},"fancybox":false,"mediumzoom":false,"lazyload":false,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"algolia":{"hits":{"per_page":10},"labels":{"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}},"localsearch":{"enable":false,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false},"motion":{"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}}};
  </script>

  <meta name="description" content="程序猿">
<meta property="og:type" content="website">
<meta property="og:title" content="马天">
<meta property="og:url" content="http://matian.connorma.cn/index.html">
<meta property="og:site_name" content="马天">
<meta property="og:description" content="程序猿">
<meta property="og:locale" content="zh_CN">
<meta property="article:author" content="马天">
<meta name="twitter:card" content="summary">

<link rel="canonical" href="http://matian.connorma.cn/">


<script id="page-configurations">
  // https://hexo.io/docs/variables.html
  CONFIG.page = {
    sidebar: "",
    isHome : true,
    isPost : false,
    lang   : 'zh-CN'
  };
</script>

  <title>马天</title>
  






  <noscript>
  <style>
  .use-motion .brand,
  .use-motion .menu-item,
  .sidebar-inner,
  .use-motion .post-block,
  .use-motion .pagination,
  .use-motion .comments,
  .use-motion .post-header,
  .use-motion .post-body,
  .use-motion .collection-header { opacity: initial; }

  .use-motion .site-title,
  .use-motion .site-subtitle {
    opacity: initial;
    top: initial;
  }

  .use-motion .logo-line-before i { left: initial; }
  .use-motion .logo-line-after i { right: initial; }
  </style>
</noscript>

</head>

<body itemscope itemtype="http://schema.org/WebPage">
  <div class="container use-motion">
    <div class="headband"></div>

    <header class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-brand-container">
  <div class="site-nav-toggle">
    <div class="toggle" aria-label="切换导航栏">
      <span class="toggle-line toggle-line-first"></span>
      <span class="toggle-line toggle-line-middle"></span>
      <span class="toggle-line toggle-line-last"></span>
    </div>
  </div>

  <div class="site-meta">

    <a href="/" class="brand" rel="start">
      <span class="logo-line-before"><i></i></span>
      <h1 class="site-title">马天</h1>
      <span class="logo-line-after"><i></i></span>
    </a>
  </div>

  <div class="site-nav-right">
    <div class="toggle popup-trigger">
    </div>
  </div>
</div>




<nav class="site-nav">
  <ul id="menu" class="main-menu menu">
        <li class="menu-item menu-item-home">

    <a href="/" rel="section"><i class="fa fa-home fa-fw"></i>首页</a>

  </li>
        <li class="menu-item menu-item-about">

    <a href="/about/" rel="section"><i class="fa fa-user fa-fw"></i>关于</a>

  </li>
        <li class="menu-item menu-item-tags">

    <a href="/tags/" rel="section"><i class="fa fa-tags fa-fw"></i>标签</a>

  </li>
        <li class="menu-item menu-item-categories">

    <a href="/categories/" rel="section"><i class="fa fa-th fa-fw"></i>分类</a>

  </li>
        <li class="menu-item menu-item-archives">

    <a href="/archives/" rel="section"><i class="fa fa-archive fa-fw"></i>归档</a>

  </li>
  </ul>
</nav>




</div>
    </header>

    
  <div class="back-to-top">
    <i class="fa fa-arrow-up"></i>
    <span>0%</span>
  </div>


    <main class="main">
      <div class="main-inner">
        <div class="content-wrap">
          

          <div class="content index posts-expand">
            
      
  
  
  <article itemscope itemtype="http://schema.org/Article" class="post-block" lang="zh-CN">
    <link itemprop="mainEntityOfPage" href="http://matian.connorma.cn/4978e888.html">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="马天">
      <meta itemprop="description" content="程序猿">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="马天">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          
            <a href="/4978e888.html" class="post-title-link" itemprop="url">bitmap的应用—内容标签场景的存储方案</a>
        </h2>

        <div class="post-meta">
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-calendar"></i>
              </span>
              <span class="post-meta-item-text">发表于</span>

              <time title="创建时间：2023-02-07 18:22:23" itemprop="dateCreated datePublished" datetime="2023-02-07T18:22:23+08:00">2023-02-07</time>
            </span>
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-folder"></i>
              </span>
              <span class="post-meta-item-text">分类于</span>
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/categories/%E5%9C%BA%E6%99%AF%E7%A4%BA%E4%BE%8B/" itemprop="url" rel="index"><span itemprop="name">场景示例</span></a>
                </span>
            </span>

          

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
          <p>在之前特意穿插了一篇介绍bitmap的笔记<a href="/660efd9a.html" title="bitmap与布隆过滤器">bitmap与布隆过滤器</a>，这里将介绍一个bitmap的应用场景，为了避免可能的风险，将具体的业务替换成了类似的场景。</p>
<p>需要开发一个图片标签功能：</p>
<ul>
<li>用户发布图片时，可以为图片选择预置标签或新增标签；已发布的图片可以增加&#x2F;移除标签；一张图片的标签不重复，标签数量限制不能完全确定但是不会很多（十个以内）</li>
<li>系统预置标签主要是常用的、较为标准化的，如二次元、水墨画、动漫风等。系统预置标签的文本可以修改，比如 动漫–&gt;动漫风</li>
<li>对用户新增的标签，不能再修改或删除标签内容；标签任意人可以使用，标签文本一致即认为相同</li>
<li>可以按单个标签或者多个标签联合使用（交、并、差）来筛选图片</li>
</ul>
<p>针对这一场景，设想了以下的几种方案，一一来进行说明</p>
          <!--noindex-->
            <div class="post-button">
              <a class="btn" href="/4978e888.html#more" rel="contents">
                阅读全文 &raquo;
              </a>
            </div>
          <!--/noindex-->
        
      
    </div>

    
    
    
      <footer class="post-footer">
        <div class="post-eof"></div>
      </footer>
  </article>
  
  
  

      
  
  
  <article itemscope itemtype="http://schema.org/Article" class="post-block" lang="zh-CN">
    <link itemprop="mainEntityOfPage" href="http://matian.connorma.cn/660efd9a.html">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="马天">
      <meta itemprop="description" content="程序猿">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="马天">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          
            <a href="/660efd9a.html" class="post-title-link" itemprop="url">bitmap与布隆过滤器</a>
        </h2>

        <div class="post-meta">
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-calendar"></i>
              </span>
              <span class="post-meta-item-text">发表于</span>

              <time title="创建时间：2023-01-20 11:08:13" itemprop="dateCreated datePublished" datetime="2023-01-20T11:08:13+08:00">2023-01-20</time>
            </span>
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-folder"></i>
              </span>
              <span class="post-meta-item-text">分类于</span>
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/categories/%E6%96%B9%E6%B3%95%E8%AE%BA/" itemprop="url" rel="index"><span itemprop="name">方法论</span></a>
                </span>
            </span>

          

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
          <p>bitmap，这个词在许多开发场景中都会出现，比如安卓原生开发中Bitmap用于存储位图图片，但这里我们说到的bitmap是指更常见的一个数据结构，将数据按照某种规则（比如整数按照索引位置）映射到某个bit位，从而使用紧凑的bit结构记录大规模数据集合的数据状态。</p>
<p>bitmap的一大特点是适合的是记录大规模整数的有无状态：每个bit存储一条整数的有无状态，bitmap这一紧凑的结构就能使用极少的空间完成大量整数的状态的记录，进行快捷的查找、排序和统计。而bit为单位的存储又将带来位运算上便捷的交、并等集合运算，多个bitmap之间便捷的交、并等集合运算，在索引、标签存储等场景又极适合，我们将在另一篇文章中尝试给出一个示例。</p>
          <!--noindex-->
            <div class="post-button">
              <a class="btn" href="/660efd9a.html#more" rel="contents">
                阅读全文 &raquo;
              </a>
            </div>
          <!--/noindex-->
        
      
    </div>

    
    
    
      <footer class="post-footer">
        <div class="post-eof"></div>
      </footer>
  </article>
  
  
  

      
  
  
  <article itemscope itemtype="http://schema.org/Article" class="post-block" lang="zh-CN">
    <link itemprop="mainEntityOfPage" href="http://matian.connorma.cn/e6a6b472.html">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="马天">
      <meta itemprop="description" content="程序猿">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="马天">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          
            <a href="/e6a6b472.html" class="post-title-link" itemprop="url">nginx+lua(OpenResty)实现代理日志文件指定行读取</a>
        </h2>

        <div class="post-meta">
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-calendar"></i>
              </span>
              <span class="post-meta-item-text">发表于</span>

              <time title="创建时间：2023-01-06 08:41:24" itemprop="dateCreated datePublished" datetime="2023-01-06T08:41:24+08:00">2023-01-06</time>
            </span>
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-folder"></i>
              </span>
              <span class="post-meta-item-text">分类于</span>
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/categories/nginx/" itemprop="url" rel="index"><span itemprop="name">nginx</span></a>
                </span>
            </span>

          

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
          <p>在开发的任务调度平台中，任务执行日志分布在各个机器上，希望用户可以无感知的查看任务的执行日志内容。但日志的数量、大小较大，统一存储将带来较大的存储压力；使用任务执行器后端程序读取指定日志文件并在API响应中返回，这种方式可定制程度最高，在许多的大数据、任务调度开源项目中使用了这种方式实现。</p>
<p>本文将介绍另一种简单易行的方式，使用nginx代理静态日志文件，通过lua脚本读取日志文件的指定行并返回；这种方式需要每台任务执行器所在的机器都提供一个nginx代理，希望只对外暴露一个入口的话那么可以在这些nginx节点之上再增加一层nginx代理，按照节点IP路由。或者，可以通过NFS等方式将日志文件写到网络文件地址中，这样只需要一个nginx读取NFS的共享文件，大量写入的情况下NFS的稳定性、读写性能是否会存在问题？其实按照之前的实际经历，大数据平台任务的shuffle数据写入NFS&#x2F;Ceph，难免会出现性能下降或者IO的“毛刺”等诸多问题，不过对一般的任务调度系统相信并不会达到这种写入量级，其实大可以放心使用。</p>
<p>本文主要将介绍使用nginx+lua实现指定读取日志行的实现，其他问题我们略过，诸位若想尝试可自行验证。</p>
<p>另外，nginx可以在编译时加入lua模块来支持lua脚本，但其实可以直接使用OpenResty（ngx_openresty，<a target="_blank" rel="noopener" href="https://github.com/openresty/openresty">github地址在这里</a>），内置了nginx，支持进行嵌入lua编程脚本，并扩展了大量的第三方模块，使得nginx不仅可用于静态代理，也完全可以通过各类module作为通用型的web应用服务器使用。本文将直接使用OpenResty来实现。</p>
          <!--noindex-->
            <div class="post-button">
              <a class="btn" href="/e6a6b472.html#more" rel="contents">
                阅读全文 &raquo;
              </a>
            </div>
          <!--/noindex-->
        
      
    </div>

    
    
    
      <footer class="post-footer">
        <div class="post-eof"></div>
      </footer>
  </article>
  
  
  

      
  
  
  <article itemscope itemtype="http://schema.org/Article" class="post-block" lang="zh-CN">
    <link itemprop="mainEntityOfPage" href="http://matian.connorma.cn/e72717fd.html">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="马天">
      <meta itemprop="description" content="程序猿">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="马天">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          
            <a href="/e72717fd.html" class="post-title-link" itemprop="url">三方应用接入与OAuth的思考</a>
        </h2>

        <div class="post-meta">
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-calendar"></i>
              </span>
              <span class="post-meta-item-text">发表于</span>

              <time title="创建时间：2022-12-29 12:10:31" itemprop="dateCreated datePublished" datetime="2022-12-29T12:10:31+08:00">2022-12-29</time>
            </span>
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-folder"></i>
              </span>
              <span class="post-meta-item-text">分类于</span>
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/categories/%E5%9C%BA%E6%99%AF%E7%A4%BA%E4%BE%8B/" itemprop="url" rel="index"><span itemprop="name">场景示例</span></a>
                </span>
            </span>

          

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
          <p>最近需要为系统添加三方应用接入的功能，对接入的三方应用允许获取用户的部分信息——但显然，不能将用户的账号、密码暴露给三方应用。这个过程中产生了一些思考，在此简单记录下。如果要一句话总结的话，就是：多学知识，学习前人的成果。</p>
<h2 id="三方应用接入需要解决的问题"><a href="#三方应用接入需要解决的问题" class="headerlink" title="三方应用接入需要解决的问题"></a>三方应用接入需要解决的问题</h2><p>三方应用接入关键的是服务端能够识别请求来源，判断是否是已授权的三方应用，所以这首先是一个身份识别的问题。</p>
<p>第二个隐含的问题是系统权限设计的问题：三方应用使用用户个人数据，是否需要用户的授权。通常这是必须的，但这次系统中面向的是内部管理应用子系统的接入授权问题，认为内部数据流转不需要此流程。</p>
<p>身份识别那么可以使用公钥私钥——但是这样，对于服务端就需要保存所有三方应用的公钥。那么也可以按照这种思路，使用一种更轻的方式：为每个合法的三方应用分配一个ID和secret密钥，三方应用请求时使用secret对内容进行签名，服务端验证签名，则可以识别请求来源的合法性。</p>
<p>基于这一思路，可以设计出一种方式：</p>
<ul>
<li>服务端为三方应用分配一个可公开的ID、一个不可公开的secret</li>
<li>三方应用使用secret对ID签名得到sign，携带自身ID与sign向服务端请求一个随机数（面向管理端子系统，默认用户同意授权），这一随机数和三方应用ID一一对应、在一定时间内有效</li>
<li>三方应用使用secret对随机数及时间戳签名，携带签名、时间戳和自身ID发起请求</li>
<li>服务端校验根据三方应用ID、随机数验证签名，并比对入参时间戳限制请求发起时间，从而确认请求来自合法的三方应用</li>
</ul>
<p>这里身份认证的可信来自于签名算法的单向和secret的私密——但也并不是非常完善的，尤其是与OAuth协议的流程对比之后。不过，<strong>稍进一步分析之后也几乎可以得到结论是，不使用https（或者类似https的非对称、对称组合）的情况下，怎么做也不安全</strong>。</p>
          <!--noindex-->
            <div class="post-button">
              <a class="btn" href="/e72717fd.html#more" rel="contents">
                阅读全文 &raquo;
              </a>
            </div>
          <!--/noindex-->
        
      
    </div>

    
    
    
      <footer class="post-footer">
        <div class="post-eof"></div>
      </footer>
  </article>
  
  
  

      
  
  
  <article itemscope itemtype="http://schema.org/Article" class="post-block" lang="zh-CN">
    <link itemprop="mainEntityOfPage" href="http://matian.connorma.cn/b2a2bcde.html">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="马天">
      <meta itemprop="description" content="程序猿">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="马天">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          
            <a href="/b2a2bcde.html" class="post-title-link" itemprop="url">jvm内存及GC分析工具</a>
        </h2>

        <div class="post-meta">
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-calendar"></i>
              </span>
              <span class="post-meta-item-text">发表于</span>

              <time title="创建时间：2022-12-12 09:30:54" itemprop="dateCreated datePublished" datetime="2022-12-12T09:30:54+08:00">2022-12-12</time>
            </span>
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-folder"></i>
              </span>
              <span class="post-meta-item-text">分类于</span>
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/categories/Java/" itemprop="url" rel="index"><span itemprop="name">Java</span></a>
                </span>
            </span>

          

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
          <p>在定位线上问题时，经常需要对JVM内存情况进行分析。在<a href="/94439062.html" title="java类加载器问题思考与简单模拟热部署">java类加载器问题思考与简单模拟热部署</a>中为了查看类代理生成情况，介绍了图形化工具HSDB的使用，而生产上进行分析更多的是使用jmap、jstat等工具，在java 8又提供了jcmd这一新的升级版工具；查看gc日志可以了解到详细的GC信息；linux提供了GDB、trace、perf等调试利器</p>
<p>然而，jmap等工具有着一些难以克服的问题：需要JVM pause导致服务暂停；开发人员需要登录服务器操作（虽然可以连接远程server，但也需要开放网络端口）；修改代码、测试需要重新打包发布。<a target="_blank" rel="noopener" href="https://arthas.aliyun.com/doc/">Arthas</a>是阿里开源的线上监控诊断产品，克服了这些缺点，支持在线解决生产问题，无需JVM重启，无需代码更改，不会暂停正在运行的线程</p>
<p>不得不提的是，不管是jmap、jstat，又或者arthas，在生产环境直接使用都是有风险的。内存的dump、线程堆栈的获取，不得不暂停JVM，即使这个过程很快，也难以完全避免服务中断；部分操作可能引起JVM崩溃，影响稳定性；等等。如何线上排查？首先的大原则是，解决问题优先于定位原因，只有在解决问题且有条件的情况下才应该扎进去定位原因；然后，根据部署情况评估是否要切走问题进程的流量后再进行排查；保护现场，尽可能留存日志、线程堆栈、内存dump等信息；想办法复现验证</p>
          <!--noindex-->
            <div class="post-button">
              <a class="btn" href="/b2a2bcde.html#more" rel="contents">
                阅读全文 &raquo;
              </a>
            </div>
          <!--/noindex-->
        
      
    </div>

    
    
    
      <footer class="post-footer">
        <div class="post-eof"></div>
      </footer>
  </article>
  
  
  

      
  
  
  <article itemscope itemtype="http://schema.org/Article" class="post-block" lang="zh-CN">
    <link itemprop="mainEntityOfPage" href="http://matian.connorma.cn/69a9ed6b.html">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="马天">
      <meta itemprop="description" content="程序猿">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="马天">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          
            <a href="/69a9ed6b.html" class="post-title-link" itemprop="url">禅道ZenTao项目管理系统源码包+nginx部署</a>
        </h2>

        <div class="post-meta">
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-calendar"></i>
              </span>
              <span class="post-meta-item-text">发表于</span>

              <time title="创建时间：2022-09-11 11:29:09" itemprop="dateCreated datePublished" datetime="2022-09-11T11:29:09+08:00">2022-09-11</time>
            </span>
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-folder"></i>
              </span>
              <span class="post-meta-item-text">分类于</span>
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/categories/%E8%BD%AF%E4%BB%B6%E9%83%A8%E7%BD%B2/" itemprop="url" rel="index"><span itemprop="name">软件部署</span></a>
                </span>
            </span>

          

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
          <p>话说程序员是块砖，哪里需要哪里搬——组里打算试用下禅道做项目管理，这里就记录下源码包部署的过程和一些基本的配置修改</p>
<p>从网上搜来的介绍：禅道是第一款国产的开源项目管理软件，她的核心管理思想基于敏捷方法scrum，内置了产品管理和项目管理，同时又根据国内研发现状补充了测试管理、计划管理、发布管理、文档管理、事务管理等功能，在一个软件中就可以将软件研发中的需求、任务、bug、用例、计划、发布等要素有序的跟踪管理起来，完整地覆盖了项目管理的核心流程。</p>
<p>禅道选用16.5版本，本身提供了一键式部署方式，内置了php(7.1)、mysql(5.7)和httpd，拖到指定路径启动就可以开始使用，但是现在已经有了mysql、nginx环境，因此使用源码包进行部署，用nginx做转发</p>
          <!--noindex-->
            <div class="post-button">
              <a class="btn" href="/69a9ed6b.html#more" rel="contents">
                阅读全文 &raquo;
              </a>
            </div>
          <!--/noindex-->
        
      
    </div>

    
    
    
      <footer class="post-footer">
        <div class="post-eof"></div>
      </footer>
  </article>
  
  
  

      
  
  
  <article itemscope itemtype="http://schema.org/Article" class="post-block" lang="zh-CN">
    <link itemprop="mainEntityOfPage" href="http://matian.connorma.cn/372d5b3e.html">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="马天">
      <meta itemprop="description" content="程序猿">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="马天">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          
            <a href="/372d5b3e.html" class="post-title-link" itemprop="url">从JDBC Driver看java SPI</a>
        </h2>

        <div class="post-meta">
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-calendar"></i>
              </span>
              <span class="post-meta-item-text">发表于</span>

              <time title="创建时间：2022-07-29 22:22:39" itemprop="dateCreated datePublished" datetime="2022-07-29T22:22:39+08:00">2022-07-29</time>
            </span>
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-folder"></i>
              </span>
              <span class="post-meta-item-text">分类于</span>
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/categories/java/" itemprop="url" rel="index"><span itemprop="name">java</span></a>
                </span>
            </span>

          

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
          <p>最近为项目整合动态多数据源，忽然想到一个问题：每种数据库需要特定的JDBC，在使用的时候只需要引入对应依赖包，那么java包是怎么引用的呢？这里至少需要解决这样的问题：</p>
<ul>
<li>必须是由java定义统一接口，各个数据库厂商或者开源社区针对数据库提供实现，不然适配这么多数据库是完全不可能也不合理的，毫无扩展性可言</li>
<li>只能在运行时加载JDBC驱动实现类，所以需要提供一种方式，使得类加载器能够找到各个驱动的实现类完成加载</li>
</ul>
<p>带着问题浏览了java.sql下的关键类，了解到这种机制称为SPI，即Service Provider Interface。这种模式适合为框架提供扩展点，不难联想到，spring通过spring.factories加载类也是SPI模式的应用</p>
          <!--noindex-->
            <div class="post-button">
              <a class="btn" href="/372d5b3e.html#more" rel="contents">
                阅读全文 &raquo;
              </a>
            </div>
          <!--/noindex-->
        
      
    </div>

    
    
    
      <footer class="post-footer">
        <div class="post-eof"></div>
      </footer>
  </article>
  
  
  

      
  
  
  <article itemscope itemtype="http://schema.org/Article" class="post-block" lang="zh-CN">
    <link itemprop="mainEntityOfPage" href="http://matian.connorma.cn/c7e143e.html">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="马天">
      <meta itemprop="description" content="程序猿">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="马天">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          
            <a href="/c7e143e.html" class="post-title-link" itemprop="url">看Spring事务机制的实现</a>
        </h2>

        <div class="post-meta">
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-calendar"></i>
              </span>
              <span class="post-meta-item-text">发表于</span>

              <time title="创建时间：2022-07-25 20:14:18" itemprop="dateCreated datePublished" datetime="2022-07-25T20:14:18+08:00">2022-07-25</time>
            </span>
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-folder"></i>
              </span>
              <span class="post-meta-item-text">分类于</span>
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/categories/Spring/" itemprop="url" rel="index"><span itemprop="name">Spring</span></a>
                </span>
            </span>

          

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
          <p>这几天给项目整合动态多数据源，遇到了事务和connection切换相关的问题，发现对Spring事务这块的代码没有仔细看过，就大体看下了Spring事务管理的实现</p>
<p>以下实现来自于sping-boot 2.6.4（spring-core 5.3.16）</p>
<p>这篇文章曾经发在掘金社区，是本人自己发布。</p>
          <!--noindex-->
            <div class="post-button">
              <a class="btn" href="/c7e143e.html#more" rel="contents">
                阅读全文 &raquo;
              </a>
            </div>
          <!--/noindex-->
        
      
    </div>

    
    
    
      <footer class="post-footer">
        <div class="post-eof"></div>
      </footer>
  </article>
  
  
  

      
  
  
  <article itemscope itemtype="http://schema.org/Article" class="post-block" lang="zh-CN">
    <link itemprop="mainEntityOfPage" href="http://matian.connorma.cn/a7ddaf0e.html">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="马天">
      <meta itemprop="description" content="程序猿">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="马天">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          
            <a href="/a7ddaf0e.html" class="post-title-link" itemprop="url">nginx实现图片缩略图</a>
        </h2>

        <div class="post-meta">
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-calendar"></i>
              </span>
              <span class="post-meta-item-text">发表于</span>

              <time title="创建时间：2022-06-18 19:59:57" itemprop="dateCreated datePublished" datetime="2022-06-18T19:59:57+08:00">2022-06-18</time>
            </span>
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-folder"></i>
              </span>
              <span class="post-meta-item-text">分类于</span>
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/categories/nginx/" itemprop="url" rel="index"><span itemprop="name">nginx</span></a>
                </span>
            </span>

          

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
          <p>项目中需要使用到缩略图功能，对比下来，使用nginx http_image_filter模块是最为快捷的方式，在此记录</p>
          <!--noindex-->
            <div class="post-button">
              <a class="btn" href="/a7ddaf0e.html#more" rel="contents">
                阅读全文 &raquo;
              </a>
            </div>
          <!--/noindex-->
        
      
    </div>

    
    
    
      <footer class="post-footer">
        <div class="post-eof"></div>
      </footer>
  </article>
  
  
  

      
  
  
  <article itemscope itemtype="http://schema.org/Article" class="post-block" lang="zh-CN">
    <link itemprop="mainEntityOfPage" href="http://matian.connorma.cn/81ee92e1.html">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="马天">
      <meta itemprop="description" content="程序猿">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="马天">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          
            <a href="/81ee92e1.html" class="post-title-link" itemprop="url">mysql8 with使用与场景示例：用户邀请记录查询</a>
        </h2>

        <div class="post-meta">
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-calendar"></i>
              </span>
              <span class="post-meta-item-text">发表于</span>

              <time title="创建时间：2022-04-07 22:02:11" itemprop="dateCreated datePublished" datetime="2022-04-07T22:02:11+08:00">2022-04-07</time>
            </span>
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-folder"></i>
              </span>
              <span class="post-meta-item-text">分类于</span>
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/categories/%E5%9C%BA%E6%99%AF%E7%A4%BA%E4%BE%8B/" itemprop="url" rel="index"><span itemprop="name">场景示例</span></a>
                </span>
            </span>

          

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
          <p>mysql8引入with语法，可将一个临时表作为本次查询生命周期内的公共表达式使用（Common Table Expressions，CTE），来简化复杂的嵌套查询，并可使用with recursive语法进行递归查询。本文对基本的使用方法进行示例，并给出了一个实际的应用场景：用户邀请记录查询</p>
          <!--noindex-->
            <div class="post-button">
              <a class="btn" href="/81ee92e1.html#more" rel="contents">
                阅读全文 &raquo;
              </a>
            </div>
          <!--/noindex-->
        
      
    </div>

    
    
    
      <footer class="post-footer">
        <div class="post-eof"></div>
      </footer>
  </article>
  
  
  

      
  
  
  <article itemscope itemtype="http://schema.org/Article" class="post-block" lang="zh-CN">
    <link itemprop="mainEntityOfPage" href="http://matian.connorma.cn/5b501ae4.html">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="马天">
      <meta itemprop="description" content="程序猿">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="马天">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          
            <a href="/5b501ae4.html" class="post-title-link" itemprop="url">mysql如何取出每个group的topN</a>
        </h2>

        <div class="post-meta">
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-calendar"></i>
              </span>
              <span class="post-meta-item-text">发表于</span>

              <time title="创建时间：2021-09-22 15:38:43" itemprop="dateCreated datePublished" datetime="2021-09-22T15:38:43+08:00">2021-09-22</time>
            </span>
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-folder"></i>
              </span>
              <span class="post-meta-item-text">分类于</span>
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/categories/mysql/" itemprop="url" rel="index"><span itemprop="name">mysql</span></a>
                </span>
            </span>

          

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
          <p>mysql在group by之后如何取出每个group下的topN？在mysql 8之前，使用max&#x2F;min函数能够取出group后某列的top1的值，但是面对topN的问题无能为力，通过子查询的方式进行解决；mysql 8引入的窗口函数对于此类组内统计很实用</p>
          <!--noindex-->
            <div class="post-button">
              <a class="btn" href="/5b501ae4.html#more" rel="contents">
                阅读全文 &raquo;
              </a>
            </div>
          <!--/noindex-->
        
      
    </div>

    
    
    
      <footer class="post-footer">
        <div class="post-eof"></div>
      </footer>
  </article>
  
  
  

      
  
  
  <article itemscope itemtype="http://schema.org/Article" class="post-block" lang="zh-CN">
    <link itemprop="mainEntityOfPage" href="http://matian.connorma.cn/cfe640d.html">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="马天">
      <meta itemprop="description" content="程序猿">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="马天">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          
            <a href="/cfe640d.html" class="post-title-link" itemprop="url">mysql全文索引的使用</a>
        </h2>

        <div class="post-meta">
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-calendar"></i>
              </span>
              <span class="post-meta-item-text">发表于</span>

              <time title="创建时间：2020-12-09 15:38:43" itemprop="dateCreated datePublished" datetime="2020-12-09T15:38:43+08:00">2020-12-09</time>
            </span>
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-folder"></i>
              </span>
              <span class="post-meta-item-text">分类于</span>
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/categories/mysql/" itemprop="url" rel="index"><span itemprop="name">mysql</span></a>
                </span>
            </span>

          

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
          <p>在mysql 5.6之前的版本，MyISAM引擎支持全文索引，但是InnoDB不支持；从mysql 5.6开始，InnoDB支持全文索引，但是不支持中文分词；从mysql 5.7.6开始，mysql内置了ngram分词器，可支持中文、日语等亚洲语种的分词。</p>
<p>全文索引fulltext index，可用于char&#x2F;varchar&#x2F;text列。在需要进行模糊查询时，如果使用 like “%target%” 进行查询，无法使用到索引。如果文本较大，为了优化效率，可以考虑全文索引。</p>
<p>本文将依次介绍以下内容：</p>
<ul>
<li>分词与倒排索引，了解全文索引的基本原理</li>
<li>mysql分词器配置与全文索引的创建</li>
<li>全文索引的使用示例</li>
</ul>
          <!--noindex-->
            <div class="post-button">
              <a class="btn" href="/cfe640d.html#more" rel="contents">
                阅读全文 &raquo;
              </a>
            </div>
          <!--/noindex-->
        
      
    </div>

    
    
    
      <footer class="post-footer">
        <div class="post-eof"></div>
      </footer>
  </article>
  
  
  

      
  
  
  <article itemscope itemtype="http://schema.org/Article" class="post-block" lang="zh-CN">
    <link itemprop="mainEntityOfPage" href="http://matian.connorma.cn/94439062.html">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="马天">
      <meta itemprop="description" content="程序猿">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="马天">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          
            <a href="/94439062.html" class="post-title-link" itemprop="url">java类加载器问题思考与简单模拟热部署</a>
        </h2>

        <div class="post-meta">
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-calendar"></i>
              </span>
              <span class="post-meta-item-text">发表于</span>

              <time title="创建时间：2020-11-14 12:10:31" itemprop="dateCreated datePublished" datetime="2020-11-14T12:10:31+08:00">2020-11-14</time>
            </span>
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-folder"></i>
              </span>
              <span class="post-meta-item-text">分类于</span>
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/categories/java/" itemprop="url" rel="index"><span itemprop="name">java</span></a>
                </span>
            </span>

          

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
          <p>java中，ClassLoader负责读取class文件、加载到JVM</p>
<h1 id="类加载过程"><a href="#类加载过程" class="headerlink" title="类加载过程"></a>类加载过程</h1><p>类加载包含的过程：</p>
<ul>
<li>加载，根据类的完全限定查找字节码文件并加载、创建一个Class对象</li>
<li>验证，验证class文件符合JVM要求</li>
<li>准备，为static变量分配内存并初始化为初始值（不管是否显式指定了初始化，都先初始化为变量类型默认的初始值）</li>
<li>解析，为常量值创建直接引用</li>
<li>初始化，类的初始化（static变量初始化、static代码块执行）</li>
</ul>
          <!--noindex-->
            <div class="post-button">
              <a class="btn" href="/94439062.html#more" rel="contents">
                阅读全文 &raquo;
              </a>
            </div>
          <!--/noindex-->
        
      
    </div>

    
    
    
      <footer class="post-footer">
        <div class="post-eof"></div>
      </footer>
  </article>
  
  
  

      
  
  
  <article itemscope itemtype="http://schema.org/Article" class="post-block" lang="zh-CN">
    <link itemprop="mainEntityOfPage" href="http://matian.connorma.cn/bdfd91d8.html">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="马天">
      <meta itemprop="description" content="程序猿">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="马天">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          
            <a href="/bdfd91d8.html" class="post-title-link" itemprop="url">rocketmq集群搭建</a>
        </h2>

        <div class="post-meta">
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-calendar"></i>
              </span>
              <span class="post-meta-item-text">发表于</span>

              <time title="创建时间：2020-09-09 23:05:02" itemprop="dateCreated datePublished" datetime="2020-09-09T23:05:02+08:00">2020-09-09</time>
            </span>
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-folder"></i>
              </span>
              <span class="post-meta-item-text">分类于</span>
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/categories/%E8%BD%AF%E4%BB%B6%E9%83%A8%E7%BD%B2/" itemprop="url" rel="index"><span itemprop="name">软件部署</span></a>
                </span>
            </span>

          

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
          <blockquote>
<p>之前自己使用rocketmq时写过一篇笔记，近期需要搭建一个rocketmq集群，发现rocketmq项目已经从apache毕业正式成为顶级项目，这里对笔记内容进行了更新，使用的版本和部署方式也按照<a target="_blank" rel="noopener" href="https://github.com/apache/rocketmq/releases/tag/rocketmq-all-4.9.4">rocketmq 4.9.4版本</a>重新进行了整理</p>
</blockquote>
<h2 id="rocketmq集群角色"><a href="#rocketmq集群角色" class="headerlink" title="rocketmq集群角色"></a>rocketmq集群角色</h2><p>rocketmq架构与kafka非常相似：rocketmq集群角色分为namesrv和broker，namesrv负责broker的注册和管理、消息向broker上队列的投递&#x2F;消费的路由，是管理节点。broker负责消息的存储、投递、查询，相当于工作节点，向指定的所有namesrv分别注册自身及管理的队列信息；每组broker可分为master和slave，写操作只可在master进行，读操作可以在任意节点进行。</p>
<p>producer向namesrv查询队列所在的broker，向这一组broker的master节点写入；consumer向namesrv查询队列所在的broker，向这一组broker的master或slave读取消息。不同组broker之间是数据分片的形式，每组broker持有一部分数据，因此可以通过扩容broker扩展消息存储量和读写性能。</p>
          <!--noindex-->
            <div class="post-button">
              <a class="btn" href="/bdfd91d8.html#more" rel="contents">
                阅读全文 &raquo;
              </a>
            </div>
          <!--/noindex-->
        
      
    </div>

    
    
    
      <footer class="post-footer">
        <div class="post-eof"></div>
      </footer>
  </article>
  
  
  

      
  
  
  <article itemscope itemtype="http://schema.org/Article" class="post-block" lang="zh-CN">
    <link itemprop="mainEntityOfPage" href="http://matian.connorma.cn/cb87a2ee.html">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="马天">
      <meta itemprop="description" content="程序猿">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="马天">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          
            <a href="/cb87a2ee.html" class="post-title-link" itemprop="url">Spring Boot @Import的使用</a>
        </h2>

        <div class="post-meta">
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-calendar"></i>
              </span>
              <span class="post-meta-item-text">发表于</span>

              <time title="创建时间：2020-03-09 17:12:54" itemprop="dateCreated datePublished" datetime="2020-03-09T17:12:54+08:00">2020-03-09</time>
            </span>
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-folder"></i>
              </span>
              <span class="post-meta-item-text">分类于</span>
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/categories/Spring/" itemprop="url" rel="index"><span itemprop="name">Spring</span></a>
                </span>
            </span>

          

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
          <p>使用@Import可以导入一个指定的@Configuration类作为一个bean（@Configuration类中定义的bean自然会注入），也可以使用@ImportResource导入other non-{@code @Configuration} bean definition resources；或者使用ImportSelector或ImportBeanDefinitionRegistrar来选择加载的bean。@Import导入的bean在所在类上使用@Autowired就可注入</p>
<p> 比如，@SpringBootApplication类默认只导入所在包层级及以下层级的bean，在这一个包之外的@Configuration类就需要使用@Import才能注入（这种情况可以使用@ComponentScan等）；比如，使用ImportSelector或ImportBeanDefinitionRegistrar，配合自定义注解，根据某些参数或者配置加载bean</p>
<p> 如自定义starter时使用的@EnableAutoConfiguration，使用了@Import(AutoConfigurationImportSelector.class)注解，AutoConfigurationImportSelector类中从META-INF&#x2F;spring.factories找出所有需要加载的configurations返回</p>
          <!--noindex-->
            <div class="post-button">
              <a class="btn" href="/cb87a2ee.html#more" rel="contents">
                阅读全文 &raquo;
              </a>
            </div>
          <!--/noindex-->
        
      
    </div>

    
    
    
      <footer class="post-footer">
        <div class="post-eof"></div>
      </footer>
  </article>
  
  
  


  
  <nav class="pagination">
    <span class="page-number current">1</span><a class="page-number" href="/page/2/">2</a><a class="page-number" href="/page/3/">3</a><a class="extend next" rel="next" href="/page/2/"><i class="fa fa-angle-right" aria-label="下一页"></i></a>
  </nav>



          </div>
          

<script>
  window.addEventListener('tabs:register', () => {
    let { activeClass } = CONFIG.comments;
    if (CONFIG.comments.storage) {
      activeClass = localStorage.getItem('comments_active') || activeClass;
    }
    if (activeClass) {
      let activeTab = document.querySelector(`a[href="#comment-${activeClass}"]`);
      if (activeTab) {
        activeTab.click();
      }
    }
  });
  if (CONFIG.comments.storage) {
    window.addEventListener('tabs:click', event => {
      if (!event.target.matches('.tabs-comment .tab-content .tab-pane')) return;
      let commentClass = event.target.classList[1];
      localStorage.setItem('comments_active', commentClass);
    });
  }
</script>

        </div>
          
  
  <div class="toggle sidebar-toggle">
    <span class="toggle-line toggle-line-first"></span>
    <span class="toggle-line toggle-line-middle"></span>
    <span class="toggle-line toggle-line-last"></span>
  </div>

  <aside class="sidebar">
    <div class="sidebar-inner">

      <ul class="sidebar-nav motion-element">
        <li class="sidebar-nav-toc">
          文章目录
        </li>
        <li class="sidebar-nav-overview">
          站点概览
        </li>
      </ul>

      <!--noindex-->
      <div class="post-toc-wrap sidebar-panel">
      </div>
      <!--/noindex-->

      <div class="site-overview-wrap sidebar-panel">
        <div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
  <p class="site-author-name" itemprop="name">马天</p>
  <div class="site-description" itemprop="description">程序猿</div>
</div>
<div class="site-state-wrap motion-element">
  <nav class="site-state">
      <div class="site-state-item site-state-posts">
          <a href="/archives/">
        
          <span class="site-state-item-count">41</span>
          <span class="site-state-item-name">日志</span>
        </a>
      </div>
      <div class="site-state-item site-state-categories">
            <a href="/categories/">
          
        <span class="site-state-item-count">17</span>
        <span class="site-state-item-name">分类</span></a>
      </div>
      <div class="site-state-item site-state-tags">
            <a href="/tags/">
          
        <span class="site-state-item-count">25</span>
        <span class="site-state-item-name">标签</span></a>
      </div>
  </nav>
</div>
  <div class="links-of-author motion-element">
      <span class="links-of-author-item">
        <a href="https://github.com/matian2014" title="GitHub → https:&#x2F;&#x2F;github.com&#x2F;matian2014" rel="noopener" target="_blank"><i class="fab fa-github fa-fw"></i>GitHub</a>
      </span>
      <span class="links-of-author-item">
        <a href="mailto:matian1103@qq.com" title="E-Mail → mailto:matian1103@qq.com" rel="noopener" target="_blank"><i class="fa fa-envelope fa-fw"></i>E-Mail</a>
      </span>
  </div>



      </div>

    </div>
  </aside>
  <div id="sidebar-dimmer"></div>


      </div>
    </main>

    <footer class="footer">
      <div class="footer-inner">
        

        
  <div class="beian"><a href="https://beian.miit.gov.cn/" rel="noopener" target="_blank">陕ICP备2023001563号 </a>
  </div>

<div class="copyright">
  
  &copy; 
  <span itemprop="copyrightYear">2025</span>
  <span class="with-love">
    <i class="fa fa-heart"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">马天</span>
</div>
  <div class="powered-by">由 <a href="https://hexo.io/" class="theme-link" rel="noopener" target="_blank">Hexo</a> & <a href="https://muse.theme-next.org/" class="theme-link" rel="noopener" target="_blank">NexT.Muse</a> 强力驱动
  </div>

        








      </div>
    </footer>
  </div>

  
  <script src="/lib/anime.min.js"></script>
  <script src="/lib/velocity/velocity.min.js"></script>
  <script src="/lib/velocity/velocity.ui.min.js"></script>

<script src="/js/utils.js"></script>

<script src="/js/motion.js"></script>


<script src="/js/schemes/muse.js"></script>


<script src="/js/next-boot.js"></script>




  















  

  

</body>
</html>
